package com.example.demo.searcher;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Parser {
    public static final String INPUT_PATH="C:\\Program Files\\Java\\docs\\api";
    Index index=new Index();

    //整个Parser类的入口
    //通过这个方法实现单线程制作索引
    public void run(){
        long beg=System.currentTimeMillis();
        System.out.println("索引制作开始!");
        ArrayList<File> fileList=new ArrayList<>();
        //根据上面指定的路径,枚举出该路径中所有的文件
        enumFile(INPUT_PATH,fileList);
        for (File f:fileList) {
            System.out.println("开始解析:"+f.getAbsolutePath());
            //解析单个html文件
            parserHtml(f);
        }
        // 把内存中构造好的索引数据结构,保存到指定的文件中
        index.save();
        long end=System.currentTimeMillis();
        System.out.println("索引制作完成!"+"消耗时间:"+(end-beg)+"ms");

    }

    //通过这个方法实现多线程制作索引
    public void runByThread() throws InterruptedException {
        long sta=System.currentTimeMillis();
        System.out.println("制作索引开始!");
        //1.枚举路径中的所有文件
        ArrayList<File> fileList=new ArrayList<>();
        enumFile(INPUT_PATH,fileList);
        //2.循环遍历文件,此处为了能够通过多线程制作索引,就直接引入线程池
        CountDownLatch latch=new CountDownLatch(fileList.size());
        ExecutorService executorService= Executors.newFixedThreadPool(4);
        for (File f:fileList ) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("解析"+f.getAbsolutePath());
                    parserHtml(f);
                    latch.countDown();
                }
            });
        }
        latch.await();
        //手动的八把线程池李的线程都干掉
        executorService.shutdown();
        //3.保存索引
        index.save();
        long end =System.currentTimeMillis();
        System.out.println("制作索引完成!"+"共消耗 "+(end-sta)+" ms!");
    }

    /**
     * 解析单个html文件
     * @param f
     */
    private void parserHtml(File f) {
        //1.解析出HTML的标题
        String title=parserTitle(f);
        //1.解析出HTML的url
        String url=parserUrl(f);
        //1.解析出HTML的正文
        String content=parserContentByRegex(f);

        //4.把解析出来的这些信息加入到索引当中
        index.addDoc(title,url,content);


    }
    public String parserContentByRegex(File f){
        //1.先把整个文件读到String里面
        String content=readFile(f);
        //2.替换掉 script 标签
        content=content.replaceAll("<script.*?>(.*?)</script>"," ");
        //3.替换掉 html 标签
        content=content.replaceAll("<.*?>"," ");
        //4.将多个空格替换为一个空格
        content=content.replaceAll("\\s+"," ");
        return content;
    }

    private String readFile(File f) {
        try(BufferedReader bufferedReader=new BufferedReader(new FileReader(f))){
            StringBuffer stringBuffer=new StringBuffer();
            while(true){
                int ret=bufferedReader.read();
                if(ret==-1){
                    break;
                }

                char c=(char)ret;
                if(c=='\n'||c=='\r'){
                    c=' ';
                }
                stringBuffer.append(c);
            }
            return stringBuffer.toString();

        }catch(IOException e){
            e.printStackTrace();

        }
        return "";
    }

    public  String parserContent(File f) {
        //手动把缓冲区设置成1M大小
        try (BufferedReader bufferedReader=new BufferedReader(new FileReader(f),1024*1024)){
            boolean isCopy=true;
            StringBuffer content=new StringBuffer();
            while(true){
                int ret=bufferedReader.read();
                if(ret==-1){
                    break;
                }
                char ch=(char)ret;
                if(ch=='<'){
                    isCopy=false;
                    continue;
                }
                if(ch=='>'){
                    isCopy=true;
                    continue;
                }
                if(ch=='\n'||ch=='\r'){
                    ch=' ';
                }
                if(isCopy){
                    content.append(ch);
                }
            }
            return content.toString();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String parserUrl(File f) {

        String str1="https://docs.oracle.com/javase/8/docs/api";
        String str2=f.getAbsolutePath().substring(INPUT_PATH.length());
        return str1+str2;
    }

    private String parserTitle(File f) {
        return  f.getName().substring(0,f.getName().length()-".html".length());
    }

    private void enumFile(String inputPath, ArrayList fileList) {
        File rootPath=new File(inputPath);
        //listFiles可以获取当前目录下的所有文件,到那时只能获取到一层.所以还要递归调用
        File[] files=rootPath.listFiles();
        for (File file:files) {
            if(file.isDirectory()){
                enumFile(file.getAbsolutePath(),fileList);
            }else{
                if(file.getAbsolutePath().endsWith(".html")){
                    fileList.add(file);
                }
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        Parser parser=new Parser();
        parser.runByThread();
    }
}
